package com.ruoyi.framework.util;

import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;

public class JwtUtil{
	// 过期时间5分钟
	public static final long EXPIRE_TIME = 5 * 60 * 1000;

	// 私钥
	public static final String SECRET = "SECRET_VALUE";

	// 请求头
	public static final String AUTH_HEADER = "X-Authorization-With";

	/**
	 * 校验token是否正确
	 * 
	 * @param token 密钥
	 * @param secret 用户的密码
	 * @return 是否正确
	 */
	public static boolean verify(String token, String username, String secret){
		try{
			Algorithm algorithm = Algorithm.HMAC256(secret);
			JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
			verifier.verify(token);
			return true;
		}catch(Exception exception){
			return false;
		}
	}

	/**
	 * 获得token中的信息无需secret解密也能获得
	 * 
	 * @return token中包含的用户名
	 */
	public static String getUsername(String token){
		try{
			DecodedJWT jwt = JWT.decode(token);
			return jwt.getClaim("username").asString();
		}catch(JWTDecodeException e){
			return null;
		}
	}

	/**
	 * 生成签名,5min后过期
	 * 
	 * @param username 用户名
	 * @param secret 用户的密码
	 * @return 加密的token
	 */
	public static String sign(String username, String secret){
		Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
		Algorithm algorithm = Algorithm.HMAC256(secret);
		// 附带username信息
		return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
	}

	/**
	 * 刷新 token的过期时间,返回一个新的token
	 */
	public static String refreshTokenExpired(String token, String secret){
		DecodedJWT jwt = JWT.decode(token);
		// 没有过期，则延长过期时间
		if(!isTokenExpired(token)){
			Map<String, Claim> claims = jwt.getClaims();
			try{
				Algorithm algorithm = Algorithm.HMAC256(secret);
				JWTCreator.Builder builer = JWT.create();
				for(Map.Entry<String, Claim> entry : claims.entrySet()){
					builer.withClaim(entry.getKey(), entry.getValue().asString());
				}
				Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
				builer.withExpiresAt(date);
				return builer.sign(algorithm);
			}catch(JWTCreationException e){
				return null;
			}
		}
		return null;
	}

	/**
	 * 获取 token的过期时间
	 */
	public static Date getExpiresAt(String token){
		try{
			DecodedJWT jwt = JWT.decode(token);
			return jwt.getExpiresAt();
		}catch(JWTDecodeException e){
			return null;
		}
	}

	/**
	 * 验证 token是否过期
	 */
	public static boolean isTokenExpired(String token){
		Date now = Calendar.getInstance().getTime();
		DecodedJWT jwt = JWT.decode(token);
		return jwt.getExpiresAt().before(now);
	}

	/**
	 * 生成16位随机盐
	 */
	public static String generateSalt(){
		SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
		String hex = secureRandom.nextBytes(16).toHex();
		return hex;
	}

}
